﻿using System;
using System.Collections.Generic;
using System.Drawing;
using BobcatUtility;
using System.Runtime.Serialization;
using CNStreaming;
using CNUtility;

namespace CNShapes
{
    /// <summary>
    /// A base class for shapes that have rectangular bounds as their defining
    /// properties. This includes boxes, ellipses and arrows for example.
    /// </summary>
    public abstract class ShapeBase_RectangularBounds : ShapeBase_DrawnWithPen
    {
        #region Public methods

        /// <summary>
        /// Returns the start point.
        /// </summary>
        /// <returns></returns>
        public PointF getStartPoint()
        {
            return m_StartPoint;
        }

        /// <summary>
        /// Sets the start point.
        /// </summary>
        public void setStartPoint(PointF startPoint, ActionOrigin actionOrigin)
        {
            // When you set the start point, we set both the start and end points as the same.
            // Otherwise the end point will be at (0, 0) and rendering will look weird.
            m_StartPoint = Utility.copy(startPoint);
            m_EndPoint = Utility.copy(startPoint);
            raiseShapeEditedEvent(actionOrigin);
        }

        /// <summary>
        /// Returns the end point.
        /// </summary>
        public PointF getEndPoint()
        {
            return m_EndPoint;
        }

        /// <summary>
        /// Sets the end point.
        /// </summary>
        public void setEndPoint(PointF endPoint, ActionOrigin actionOrigin)
        {
            m_EndPoint = Utility.copy(endPoint);
            raiseShapeEditedEvent(actionOrigin);
        }

        #endregion

        #region IStreamable members

        /// <summary>
        /// Serializes this class's data to the stream passed in.
        /// </summary>
        public override void toStream(MessageStream stream)
        {
            base.toStream(stream);
            stream.writePointF(m_StartPoint);
            stream.writePointF(m_EndPoint);
        }

        /// <summary>
        /// Reads this object's data from the stream passed in.
        /// </summary>
        public override void fromStream(MessageStream stream, int iVersion)
        {
            base.fromStream(stream, iVersion);
            m_StartPoint = stream.readPointF();
            m_EndPoint = stream.readPointF();
        }

        /// <summary>
        /// Returns the message version.
        /// </summary>
        public override int getMessageVersion()
        {
            return 1;
        }

        #endregion

        #region Shape members

        /// <summary>
        /// Returns the bounds of this shape.
        /// </summary>
        public override RectangleF getBounds(Graphics graphics)
        {
            float x = Math.Min(m_StartPoint.X, m_EndPoint.X);
            float y = Math.Min(m_StartPoint.Y, m_EndPoint.Y);
            float width = Math.Abs(m_StartPoint.X - m_EndPoint.X);
            float height = Math.Abs(m_StartPoint.Y - m_EndPoint.Y);
            return new RectangleF(x, y, width, height);
        }

        #endregion

        #region Protected data

        // The start and end point of the arrow.
        protected PointF m_StartPoint = new PointF();
        protected PointF m_EndPoint = new PointF();

        #endregion
    }
}
